<?php
class IdentityMap
{
    private static $_identityMap;

    private $_objects = array();

    private function __construct()
    {
    }

    public static function getInstance()
    {
        if ( !isset(self::$_identityMap)) {
            self::$_identityMap = new self();
        }
        return self::$_identityMap;
    }
     
    public static function globalKey(Identifyable $object)
    {
        return self::getInstance()->_globalKey($object);
    }
    
    protected function _globalKey(Identifyable $object)
    {
        return get_class($object).$object->getId();
    }

    public static function add(Identifyable $object)
    {
        return self::getInstance()->add($object);
    }
    
    public static function add(Identifyable $object)
    {
        if ($this->_contains($object)) {
            return false;
        } else {
            $key = $this->_globalKey($object);
            $this->_objects[$key] = $object;
        }
    }
    
    public static function remove(Identifyable $object)
    {
        return self::getInstance()->_remove($object);
    }
     
    protected function _remove(Identifyable $object)
    {
        unset($this->_objects[$this->_globalKey($object)]);
        return true;
    }

    public static function exists($className, $id)
    {
        return self::getInstance()->_exists($className, $id);
    }

    protected function _exists($className, $id)
    {
        $key = "{$className}{$id}";
        return (array_key_exists($key, $this->_objects))
               ? $this->_objects[$key];
               : false;
    }
    
    public static function contains(Identifyable $object)
    {
        return self::getInstance()->_contains($object);
    }

    protected function _contains(Identifyable $object)
    {
        return array_key_exists($this->_globalKey($object), $this->_objects);
    }

}
